using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using OpenComposite.EII.Repository;

namespace OpenComposite.EII.Designer.BObjects
{
	public partial class FormBusinessObjectField : Form
	{
		#region Initialization
		public FormBusinessObjectField(IServiceProvider serviceProvider, int RepositoryID, int DomainID)
		{
			InitializeComponent();

			_idRepository = RepositoryID;
			_idDomain = DomainID;
			_serviceProvider = serviceProvider;

			addBusinessObjectsToDataTypeList();

			cmbDataType.SelectedItem = "string";
		}

		#endregion

		#region Public Members

		#region Properties
		public Noun Noun
		{
			get { return _noun; }
			set {
				_noun = value;

				txtName.Text = _noun.Name;
				txtName.ReadOnly = true;
				txtName.BackColor = SystemColors.Window;
				cmbDataType.Text = _noun.DataType;
				cmbDataType.Enabled = false;
			}
		}
		public BusinessObject BusinessObject
		{
			get { return _bobject; }
			//private set
			//{
			//    _noun = value;

			//    txtName.Text = _bobject.Name;
			//    txtName.ReadOnly = true;
			//    txtName.BackColor = SystemColors.Window;
			//    cboDataType.Text = _bobject.Name;
			//    cboDataType.Enabled = false;
			//}
		}
		public string NounName
		{
			get { return txtName.Text; }
			set { txtName.Text = value; }
		}
		public string DataType
		{
			get { return cmbDataType.Text; }
			set { cmbDataType.Text = value; }
		}
		public int MinOccurs
		{
			get {
				int min = 0;
				if ( cmbMinOccurs.Text == unbounded )
					min = -1;
				else if ( !int.TryParse(cmbMinOccurs.Text, out min) )
					min = 1;
				return min;
			}
			set {
				if ( value < 0 )
					cmbMinOccurs.Text = unbounded;
				else
					cmbMinOccurs.Text = value.ToString();
			}
		}
		public int MaxOccurs
		{
			get
			{
				int max = 0;
				if ( cmbMaxOccurs.Text == unbounded )
					max = -1;
				else if ( !int.TryParse(cmbMaxOccurs.Text, out max) )
					max = 1;
				return max;
			}
			set
			{
				if ( value < 0 )
					cmbMaxOccurs.Text = unbounded;
				else
					cmbMaxOccurs.Text = value.ToString();
			}
		}
		public BusinessObject Reference
		{
			get { return cmbDataType.SelectedItem as BusinessObject; 
			}
			set {
				if ( value == null )
					return;
				foreach ( object obj in cmbDataType.Items ) {
					BusinessObject bo = obj as BusinessObject;
					if ( bo != null && bo.ID == value.ID ) {
						cmbDataType.SelectedItem = bo;
						break;
					}
				}
			}
		}
		#endregion

		#endregion

		#region Private Members

		#region Variables
		private const string unbounded = "unbounded";

		private int _idRepository = -1;
		private int _idDomain = -1;
		private Noun _noun = null;
		private BusinessObject _bobject = null;

		private IServiceProvider _serviceProvider;
		#endregion

		#region Methods
		private void selectNoun()
		{
			Forms.FormSelectRepositoryEx frm = new OpenComposite.EII.Forms.FormSelectRepositoryEx(_serviceProvider);
			frm.ShowAllDomains = true;
			frm.ShowAllFolders = false;
			frm.AllowChangeDomain = true;
			frm.AllowChangeType = false;
			frm.AllowCreateNewItem = true;
			frm.MultiSelect = false;
			frm.AllowedTypes = new ItemType[] { ItemType.Noun };
			frm.RepositoryID = Global.Status.CurrentRepositoryId;
			frm.DomainID = Global.Status.CurrentDomainId;
			if ( frm.ShowDialog() == DialogResult.OK ) {
				List<IRepositoryItem> lstSelected = frm.GetSelectedItems();
				if ( lstSelected.Count > 0 && lstSelected[0] is Noun ) {
					_noun = (Noun)lstSelected[0];
					txtName.Text = _noun.Name;
					txtName.ReadOnly = true;
					txtName.BackColor = SystemColors.Window;
					cmbDataType.Text = _noun.DataType;
					cmbDataType.Enabled = false;
				}
			}
			//FormVocabularySelect form = new FormVocabularySelect(_serviceProvider, _idRepository);
			//if ( form.ShowDialog() == DialogResult.OK && form.SelectedNoun != null ) {
			//    _noun = form.SelectedNoun;

			//    txtName.Text = _noun.Name;
			//    txtName.ReadOnly = true;
			//    txtName.BackColor = SystemColors.Window;
			//    cboDataType.Text = _noun.DataType;
			//    cboDataType.Enabled = false;
			//}
		}

		private void selectBusinessObject()
		{
			Forms.FormSelectRepositoryEx frm = new OpenComposite.EII.Forms.FormSelectRepositoryEx(_serviceProvider);
			frm.ShowAllDomains = true;
			frm.ShowAllFolders = false;
			frm.AllowChangeDomain = true;
			frm.AllowChangeType = false;
			frm.AllowCreateNewItem = true;
			frm.MultiSelect = false;
			frm.AllowedTypes = new ItemType[] { ItemType.BObject };
			frm.RepositoryID = Global.Status.CurrentRepositoryId;
			frm.DomainID = Global.Status.CurrentDomainId;
			if ( frm.ShowDialog() == DialogResult.OK ) {
				List<IRepositoryItem> lstSelected = frm.GetSelectedItems();
				if ( lstSelected.Count > 0 && lstSelected[0] is BusinessObject ) {
					_bobject = (BusinessObject)lstSelected[0];
					txtName.Text = _bobject.Name;
					//txtName.ReadOnly = true;
					//txtName.BackColor = SystemColors.Window;
					cmbDataType.Text = _bobject.Name;
					cmbDataType.Enabled = false;
				}
			}
		}

		private void createNoun()
		{
			RepositoryService repSvc = (RepositoryService)_serviceProvider.GetService(typeof(RepositoryService));
			if ( repSvc == null )
				throw new NullReferenceException("RepositoryService not available.");

			//bool bSaveContinue;
			IRepositoryItem item = repSvc.GetItem(ItemType.Noun, true, _idRepository);
			if ( item != null && item is Noun ) {
				Global.Data.AddRepositoryItemToDomainFolder(_idDomain, item);
				_noun = (Noun)item;

				txtName.Text = _noun.Name;
				txtName.ReadOnly = true;
				txtName.BackColor = SystemColors.Window;
				cmbDataType.SelectedItem = _noun.DataType;
				cmbDataType.Enabled = true;
			}
		}
		private void open()
		{
		}
		private void close(DialogResult result)
		{
			if ( result == DialogResult.OK ) {
				if ( MaxOccurs != 1 && txtName.Text == cmbDataType.Text ) {
					MessageBox.Show("If the Maximum Occurances is set to a value more than 1, the Name of the element must be different than the name of the business object (data type). Please change the name of the element in the 'Name' field.",
						"Business Object Field", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
					txtName.Focus();
					txtName.Select(txtName.Text.Length, 0);
					return;
				}
			}
			//if ( result == DialogResult.OK && _noun != null ) {
				//_noun.DataType = cboDataType.Text;
				//_noun.Save();
			//}
			this.DialogResult = result;
			this.Close();
		}

		private void addBusinessObjectsToDataTypeList()
		{
			RepositoryService repSvc = (RepositoryService)_serviceProvider.GetService(typeof(RepositoryService));
			if ( repSvc == null )
				throw new NullReferenceException("RepositoryService not available.");

			DataRow[] drBOs = Global.Data.GetRepositoryItemsOfDomainFolderTypeRecursive(Global.Status.CurrentDomainId, ItemType.BObject);
			if ( drBOs != null ) {
				cmbDataType.BeginUpdate();
				if ( drBOs.Length > 0 )
					cmbDataType.Items.Add("---");
				foreach ( DataRow row in drBOs ) {
					if ( (ItemType)row["type"] == ItemType.BObject )
						cmbDataType.Items.Add(repSvc.GetItem(ItemType.BObject, (int)row["id"], false));
				}
				cmbDataType.EndUpdate();
			}
		}
		#endregion

		#region Event Handlers
		private void FormBusinessObjectField_FormClosing(object sender, FormClosingEventArgs e)
		{
			if ( this.DialogResult == DialogResult.OK ) {
				// validate form at form closing
				if ( txtName.Text.Trim() == "" ) {
					if ( MessageBox.Show("Please select an existing noun or create a new noun.", "Business Object Field", MessageBoxButtons.OKCancel, MessageBoxIcon.Exclamation)
						 == DialogResult.Cancel ) {
						this.DialogResult = DialogResult.Cancel;
					} else {
						btnSelNoun.Focus();
						e.Cancel = true;
					}
				}
			}
		}

		private void FormBusinessObjectField_Validating(object sender, CancelEventArgs e)
		{
		}

		private void btnNewNoun_Click(object sender, EventArgs e)
		{
			createNoun();
		}

		private void btnSelNoun_Click(object sender, EventArgs e)
		{
			selectNoun();
		}
		private void tsbtnOK_Click(object sender, EventArgs e)
		{
			close(DialogResult.OK);
		}
		private void tsbtnCancel_Click(object sender, EventArgs e)
		{
			close(DialogResult.Cancel);
		}

		private void btnSelectDataTypeFromBO_Click(object sender, EventArgs e)
		{
			selectBusinessObject();
		}

		private void cboDataType_DrawItem(object sender, DrawItemEventArgs e)
		{
			
		}

		private void txtName_KeyPress(object sender, KeyPressEventArgs e)
		{
			e.Handled = !Helpers.IsValidCharForName(e.KeyChar);
		}

		#endregion

		#endregion

	}
}